package com.rtsapp.server.gamelog.analyze.stat.income;

import com.alibaba.fastjson.JSONObject;
import com.rtsapp.server.gamelog.analyze.dao.IncomeDao;
import com.rtsapp.server.gamelog.analyze.stat.income.model.IncomeTargetInfo;

import java.util.Calendar;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by liwang on 17-2-9.
 * <p>
 * 管理收入指标
 */
public class IncomeTargetMgr {

    private final IncomeDao incomeDao;

    // <游戏ID, <地区ID, <年份, <月份, 收入指标>>>>
    private ConcurrentMap<String, ConcurrentMap<String, ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>>>> incomeTargetMap = new ConcurrentHashMap<>( );


    public IncomeTargetMgr( IncomeDao incomeDao ) {
        this.incomeDao = incomeDao;

        initialize( );
    }

    private void initialize( ) {

        // 从数据库查询出收入指标
        List<IncomeTargetInfo> list = incomeDao.selectIncomeTargetInfo( );
        for ( IncomeTargetInfo incomeTargetInfo : list ) {
            String gameId = incomeTargetInfo.gameId;
            String areaId = incomeTargetInfo.areaId;
            ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> map2 = ( ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> ) JSONObject.parse( incomeTargetInfo.year_Month_IncomeTarget_JsonStr );

            if ( map2 == null ) {
                continue;
            }

            ConcurrentMap<String, ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>>> map3 = incomeTargetMap.get( gameId );
            if ( map3 == null ) {
                map3 = new ConcurrentHashMap<>( );
                incomeTargetMap.put( gameId, map3 );
            }

            map3.put( areaId, map2 );
        }

    }

    private ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> getYearMonthIncomeTargetMap( String gameId, String areaId ) {

        ConcurrentMap<String, ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>>> map3 = incomeTargetMap.get( gameId );
        if ( map3 == null ) {
            map3 = new ConcurrentHashMap<>( );
            ConcurrentMap<String, ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>>> oldMap = incomeTargetMap.putIfAbsent( gameId, map3 );
            if ( oldMap != null ) {
                map3 = oldMap;
            }
        }

        ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> map2 = map3.get( areaId );
        if ( map2 == null ) {
            map2 = new ConcurrentHashMap<>( );
            ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> oldMap = map3.putIfAbsent( areaId, map2 );
            if ( oldMap != null ) {
                map2 = oldMap;
            }
        }

        return map2;
    }


    public ConcurrentMap<Integer, Integer> getIncomeTargetByYear( String gameId, String areaId, int targetYear, int currYear ) {
        ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> map2 = getYearMonthIncomeTargetMap( gameId, areaId );
        ConcurrentMap<Integer, Integer> map1 = map2.get( targetYear );

        if ( map1 == null && currYear <= targetYear ) {
            map1 = new ConcurrentHashMap<>( );
            for ( int i = Calendar.JANUARY; i <= Calendar.DECEMBER; i++ ) {
                map1.putIfAbsent( i, 0 );
            }

            map2.put( targetYear, map1 );

            // DB
            updateIncomeTargetToDB( gameId, areaId, map2 );
        }

        return map1;
    }



    public int getIncomeTargetByMonth( String gameId, String areaId, int year, int month ) {
        try {
            return incomeTargetMap.get( gameId ).get( areaId ).get( year ).get( month );
        } catch ( Throwable e ) {
            return 0;
        }
    }


    private void updateIncomeTargetToDB( String gameId, String areaId, ConcurrentMap<Integer, ConcurrentMap<Integer, Integer>> map ) {
        incomeDao.updateMonthIncomeTarget( gameId, areaId, JSONObject.toJSONString( map ) );
    }

    public void updateIncomeTarget( String gameId, String areaId, int year, int month, int incomeTarget ) {
        int currYear = Calendar.getInstance( ).get( Calendar.YEAR );
        ConcurrentMap<Integer, Integer> map1 = getIncomeTargetByYear( gameId, areaId, year, currYear );
        if ( map1 != null ) {
            map1.put( month, incomeTarget );

            // DB
            updateIncomeTargetToDB( gameId, areaId, getYearMonthIncomeTargetMap( gameId, areaId ) );
        }

    }
}
